package com.jy.admin.rest;

import com.aliyun.oss.model.ObjectMetadata;
import com.fqgj.base.services.oss.OSSService;
import com.fqgj.common.utils.CollectionUtils;
import com.fqgj.common.utils.HttpUtil;
import com.fqgj.common.utils.StringUtils;
import com.fqgj.common.utils.TimeUtils;
import com.fqgj.exception.common.ApplicationException;
import com.jsoniter.JsonIterator;
import com.jsoniter.any.Any;
import com.jsoniter.output.JsonStream;
import com.jy.admin.annotations.AdminSignIgnore;
import com.jy.admin.auth.anno.VisitorAccessible;
import com.jy.admin.config.ApolloConfigUtil;
import com.jy.admin.db.dao.BogConfigDao;
import com.jy.admin.db.dao.BogLogDao;
import com.jy.admin.db.dao.PendingLogDao;
import com.jy.admin.db.entity.BogConfigEntity;
import com.jy.admin.db.entity.BogLogEntity;
import com.jy.admin.db.entity.PendingLogEntity;
import com.jy.admin.enums.PendingResultTypeEnum;
import com.jy.admin.enums.PendingStatusEnum;
import com.jy.admin.rest.request.CheckingListRequest;
import com.jy.admin.rest.request.ReplyListRequest;
import com.jy.admin.rest.request.WhatsappMsgRequest;
import com.jy.admin.rest.response.CheckingListResponse;
import com.jy.admin.rest.response.ReplyListResponse;
import com.jy.bo.common.conf.api.ApiResponse;
import com.robert.vesta.util.IdUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import sun.misc.BASE64Decoder;

import java.io.*;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
 * Created with IntelliJ IDEA.
 * User: binary (mr.vencnet@gmail.com)
 * Date: 2020-06-02
 * Time: 17:18
 */
@RestController
@RequestMapping("/wa")
public class WhatsappController {

    private static final Logger LOGGER = LoggerFactory.getLogger(WhatsappController.class);

    @Autowired
    private OSSService ossService;

    @Autowired
    private ApolloConfigUtil apolloConfigUtil;

    @Autowired
    private BogConfigDao bogConfigDao;

    @Autowired
    private BogLogDao bogLogDao;

    @Autowired
    private PendingLogDao pendingLogDao;

    @AdminSignIgnore
    @RequestMapping("/record")
    @VisitorAccessible
    public ApiResponse record(@RequestBody WhatsappMsgRequest request) {
        LOGGER.info("== from ==,from:{},caption:{},robotId:{}", request.getFrom(), request.getCaption(), request.getRobotId());
        try {
            if (request.getType() == 1) {
                BogConfigEntity bogConfigEntity = bogConfigDao.selectByFrom(request.getFrom());
                if (bogConfigEntity == null) {
                    LOGGER.info("== 没有找到配置 ==,from:{}", request.getFrom());
                    return new ApiResponse(400, "config not exit");
                }

                if (StringUtils.isEmpty(request.getCaption())) {
                    LOGGER.info("== 没有找到消息说明 caption ==,from:{}", request.getFrom());
                    return new ApiResponse("");
                }

                String[] split = request.getCaption().split("\n");
                String command = split[0].trim();
                if (!command.toLowerCase().contains("/update")) {
                    LOGGER.error("== 没有找到关键词 update ==");
                    return new ApiResponse("");
                }

                String imgUrl = null;
                try {
                    imgUrl = uploadBase64ToOss(request.getData());
                    LOGGER.info("== 上传图片 成功==,url:{}", imgUrl);
                } catch (Exception e) {
                    LOGGER.error("== 上传图片 失败==", e);
                    return new ApiResponse("");
                }

                try {
                    PendingLogEntity bogLogEntity = new PendingLogEntity()
                            .setConfigCode(bogConfigEntity.getConfigCode())
                            .setImgUrl(imgUrl)
                            .setProductName(bogConfigEntity.getName())
                            .setStatus(0)
                            .setMobile("")
                            .setLoanId("")
                            .setTelMsgId("")
                            .setWaMsgId(request.getMsgId())
                            .setRequstDetail(request.getCaption().toLowerCase().replace("/update", ""))
                            .setRobotId(bogConfigEntity.getRobotId())
                            .setFromGroup(request.getFrom());

                    pendingLogDao.insert(bogLogEntity);
                } catch (Exception e) {
                    LOGGER.error("== 保存记录出错 ==", e);
                    return new ApiResponse("robot not accept");
                }
            }
        } catch (Exception e) {
            LOGGER.error("==转发异常==", e);
            return new ApiResponse("robot exception");
        }
        return new ApiResponse("robot accepted");
    }


    @AdminSignIgnore
    @RequestMapping("/reply/list")
    @VisitorAccessible
    public ApiResponse replyList(@RequestBody ReplyListRequest request) {

        LOGGER.info("=== reply list ==,request:{}", JsonStream.serialize(request));

        if (!apolloConfigUtil.getReplySwitch()) {
            LOGGER.info("=== reply list  switch not open==");
            return new ApiResponse();
        }

        if (StringUtils.isEmpty(request.getRobotId())) {
            return new ApiResponse();
        }

        List<PendingLogEntity> listByRobotIdAndStatus = pendingLogDao.getListByRobotIdAndStatus(request.getRobotId(), PendingStatusEnum.has_reply.getStatus());
        if (CollectionUtils.isEmpty(listByRobotIdAndStatus)) {
            return new ApiResponse();
        }

        ReplyListResponse replyListResponse = new ReplyListResponse(listByRobotIdAndStatus);
        listByRobotIdAndStatus.forEach(r -> {
            r.setStatus(PendingStatusEnum.replay_to_agents.getStatus());
            pendingLogDao.updateByPrimaryKey(r);
        });

        return new ApiResponse<>().setData(replyListResponse);

    }


    @RequestMapping("/list")
    public ApiResponse checkingList(@RequestBody CheckingListRequest request) {
        LOGGER.info("=== checkingList ==,request:{}", JsonStream.serialize(request));
        if (StringUtils.isEmpty(request.getDt())) {
            request.setDt(TimeUtils.toString("yyyy-MM-dd", new Date()));
        }

        List<PendingLogEntity> pendingLogEntities = pendingLogDao.searchList(request.getDt(), request.getRequestDetail(), request.getStatus(), request.getProductName());
        return new ApiResponse<>().setData(new CheckingListResponse(pendingLogEntities));

    }

    @RequestMapping("/update")
    public ApiResponse update(@RequestBody CheckingListRequest request) {
        LOGGER.info("=== update ==,request:{}", JsonStream.serialize(request));
        if (StringUtils.isEmpty(request.getDt())) {
            request.setDt(TimeUtils.toString("yyyy-MM-dd", new Date()));
        }

        PendingLogEntity pendingLogEntity = pendingLogDao.selectById(request.getId());
        if (pendingLogEntity == null) {
            return new ApiResponse().setCode(99);
        }

        if (request.getStatus() != null) {
            pendingLogEntity.setStatus(request.getStatus());
        }

        if (StringUtils.isNotEmpty(request.getResultContent())) {
            pendingLogEntity.setReplyDetail(request.getResultContent());
        }

        if (StringUtils.isNotEmpty(request.getCode12())) {
            pendingLogEntity.setTransctionNo(request.getCode12());
        }
        if (StringUtils.isNotEmpty(request.getLoanId())) {
            pendingLogEntity.setLoanId(request.getLoanId());
        }
        if (StringUtils.isNotEmpty(request.getLoanId()) && StringUtils.isNotEmpty(request.getCode12())) {
            pendingLogEntity.setStatus(PendingStatusEnum.detail_ready.getStatus());
        }

        if (StringUtils.isNotEmpty(request.getRepaymentDate())) {
            pendingLogEntity.setRepaymentDate(request.getRepaymentDate());
        }

        pendingLogDao.updateByPrimaryKey(pendingLogEntity);
        return new ApiResponse();
    }

    @RequestMapping("/manual/reply")
    public ApiResponse doAction(@RequestBody CheckingListRequest request) {
        if (request.getId() == null) {
            throw new ApplicationException("params lack");
        }

        if (StringUtils.isEmpty(request.getResultContent())) {
            throw new ApplicationException("params lack");
        }

        PendingLogEntity pendingLogEntity = pendingLogDao.selectById(request.getId());
        if (pendingLogEntity == null) {
            throw new ApplicationException("record not exist");
        }

        pendingLogEntity.setResultContent(request.getResultContent())
                .setStatus(PendingStatusEnum.has_reply.getStatus())
                .setResultType(PendingResultTypeEnum.manual_reply.getType())
        ;

        pendingLogDao.updateByPrimaryKey(pendingLogEntity);
        return new ApiResponse();
    }

    public String uploadBase64ToOss(String base64Img) {
        String uuid = IdUtils.genId() + "";
        String fileName = (apolloConfigUtil.isServerTest() ? "excel/test/" + uuid : "whatsapp/" + uuid) + ".png";
        ByteArrayOutputStream outputStream = null;
        InputStream in1 = null;

//        base64Img = base64Img.split(",")[1];
        BASE64Decoder decoder = new BASE64Decoder();
        try {

            byte[] file = decoder.decodeBuffer(base64Img);

            ObjectMetadata objectMeta = new ObjectMetadata();

            objectMeta.setContentLength(file.length);

            InputStream inputStream = new ByteArrayInputStream(file);
            outputStream = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int len;
            while ((len = inputStream.read(buffer)) > -1) {
                outputStream.write(buffer, 0, len);
            }
            outputStream.flush();
            in1 = new ByteArrayInputStream(outputStream.toByteArray());
            ossService.uploadFile(apolloConfigUtil.getBucketName(), in1, file.length, fileName);
//            LOGGER.info("上传成功:{},url:{}", fileName, apolloConfigUtil.getOssBaseUrl() + fileName);
        } catch (Exception e) {
//            LOGGER.error("上传失败，userCode:" + merchantCode + ",exception:" + e);
            throw new ApplicationException("picture upload failed");
        } finally {
            try {
                if (outputStream != null) {
                    outputStream.close();
                }
                if (in1 != null) {
                    in1.close();
                }
//                if (in2 != null) {
//                    in2.close();
//                }
            } catch (IOException var15) {
            }
        }
        return apolloConfigUtil.getOssBaseUrl() + "/" + fileName;
    }

}
